package com.idiot.web.cloudDisk;

import com.idiot.domain.common.utils.FileUtils;
import com.idiot.domain.common.utils.ResponseUtils;
import com.idiot.domain.model.Directory;
import com.idiot.domain.model.DirectoryType;
import com.idiot.domain.model.FileInfo;
import com.idiot.web.base.SuperController;
import com.idiot.service.IDirectoryService;
import com.idiot.service.IDirectoryTypeService;
import com.idiot.service.IFileService;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * Created by idiot on 2016/12/20.
 * @description 管理目录
 */
@Controller
@RequestMapping(value = "cloudDisk/content")
public class ContentController extends SuperController {

    @Resource
    private IDirectoryService directoryService;
    @Resource
    private IDirectoryTypeService directoryTypeService;
    @Resource
    private IFileService fileService;

    //加载page页面
    @RequiresPermissions(value = "cloudDisk:content:page")
    @RequestMapping(value = "page", method = RequestMethod.GET)
    public String toPage(Model model){
        return "cloudDisk/content/page";
    }

    //根据目录编号加载目录 和 文件信息
    @RequestMapping(value = "data", method = RequestMethod.POST)
    public String data(Model model, Long parentDirectoryId, boolean preLevel){
        if(preLevel){
            //根据目录编号加载目录信息
            Directory directory = directoryService.getDirectoryByDirectoryId(parentDirectoryId);
            parentDirectoryId = directory.getParentDirectoryId();
        }
        //根据目录父级编号  加载目录信息
        List<Directory> directoryList = directoryService.getDirectoryByParentDirectoryId(parentDirectoryId);
        List<FileInfo> fileList = new ArrayList<FileInfo>();    //该目录下的文件信息
        if(parentDirectoryId != 0){
            //获取目录下的文件信息
            fileList = fileService.getFilesByDirectoryId(parentDirectoryId);
        }
        model.addAttribute("parentDirectoryId", parentDirectoryId);
        model.addAttribute("lists", directoryList);
        model.addAttribute("fileList", fileList);
        return "cloudDisk/content/data";
    }

    //前往编辑页面
    @RequestMapping(value = "directory/toUpdate", method = RequestMethod.GET)
    public String toAdd(Model model, Long parentDirectoryId){
        List<DirectoryType> directoryTypeList = directoryTypeService.getAllValidDirectoryTypes();
        model.addAttribute("directoryTypeList", directoryTypeList);
        model.addAttribute("parentDirectoryId", parentDirectoryId);
        return "cloudDisk/content/update";
    }

    //编辑目录信息
    @RequestMapping(value = "directory/update", method = RequestMethod.POST)
    public void update(Model model, Directory info){
        //directoryId为空/0时表示   新增操作
        if(0 == info.getDirectoryId()){
            directoryService.insert(info);
            ResponseUtils.writeSuccessReponse(request, response, "新增目录信息成功");
        }else {     //修改操作
            directoryService.update(info);
            ResponseUtils.writeSuccessReponse(request, response, "修改目录信息成功");
        }
    }

    //前往上传文件页面
    @RequestMapping(value = "file/toUpload", method = RequestMethod.GET)
    public String toUpload(Model model, Long parentDirectoryId){
        //获取目录编码
        if(parentDirectoryId != 0){
            Directory directory = directoryService.getDirectoryByDirectoryId(parentDirectoryId);
            DirectoryType directoryType = directoryTypeService.getDirectoryTypeByDirectoryTypeId(directory.getDirectoryTypeId());
            String uploadPath = directoryType.getDisk()+"/"+directoryType.getCode()+"/"+directory.getPathCode();
            model.addAttribute("uploadPath", uploadPath);
            model.addAttribute("directoryId", directory.getDirectoryId());
        }
        return "cloudDisk/content/upload";
    }

    //上传文件操作
    @RequestMapping(value = "file/upload", method = RequestMethod.POST)
    @ResponseBody
    public String upload(HttpServletRequest request){
        String uploadPath = request.getParameter("uploadPath"); //上传路径
        String id = request.getParameter("id");                 //文件的id  之后用于临时目录
        long directoryId = Long.parseLong(request.getParameter("directoryId"));
        MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest)request;
        // 如果大于1说明是分片处理
        int chunks = 1;
        int chunk = 0;
        //取得request中的所有文件名
        Iterator<String> iterator = multiRequest.getFileNames();
        if(multiRequest.getParameter("chunks") != null){
            chunks = Integer.parseInt(multiRequest.getParameter("chunks"));
            chunk = Integer.parseInt(multiRequest.getParameter("chunk"));
        }
        try {
            while(iterator.hasNext()) {
                //取得上传文件
                MultipartFile file = multiRequest.getFile(iterator.next());
                if (file != null) {
                    //取得当前上传文件的文件名称
                    String myFileName = file.getOriginalFilename();
                    // 临时目录用来存放所有分片文件
                    String tempFileDirStr = uploadPath + "/" + id;
                    File tempFileDir = new File(tempFileDirStr);
                    if (!tempFileDir.exists()) {
                        tempFileDir.mkdirs();
                    }
                    // 分片处理时，前台会多次调用上传接口，每次都会上传文件的一部分到后台(默认每片为5M)
                    File tempPartFile = new File(tempFileDir, myFileName + "_" + chunk + ".part");
                    FileUtils.copyInputStreamToFile(file, tempPartFile);
                    // 是否全部上传完成
                    // 所有分片都存在才说明整个文件上传完成
                    boolean uploadDone = true;
                    for (int i = 0; i < chunks; i++) {
                        File partFile = new File(tempFileDir, myFileName + "_" + i + ".part");
                        if (!partFile.exists()) {
                            uploadDone = false;
                        }
                    }
                    // 所有分片文件都上传完成
                    // 将所有分片文件合并到一个文件中  得到 destTempFile 就是最终的文件  然后保存即可
                    if (uploadDone) {
                        File destTempFile = new File(uploadPath, myFileName);
                        for (int i = 0; i < chunks; i++) {
                            File partFile = new File(tempFileDir, myFileName + "_" + i + ".part");
                            //合并分片文件
                            FileUtils.copyFile(partFile, destTempFile);
                        }
                        //删除临时文件夹 以及里面的文件
                        FileUtils.deleteDirectory(tempFileDir);
                        //更新数据库
                        FileInfo fileInfo = new FileInfo();
                        fileInfo.setFileName(destTempFile.getName());
                        fileInfo.setDirectoryId(directoryId);
                        fileInfo.setDirectoryPath(uploadPath);
                        fileService.upload(fileInfo);
                    } else {
                        // 临时文件创建失败  删除临时文件夹 以及里面的文件
                        if (chunk == chunks -1) {
                            FileUtils.deleteDirectory(tempFileDir);
                            return ResponseUtils.responseError("上传文件失败");
                        }
                    }
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return ResponseUtils.responseSuccess("上传文件成功");
    }
}
